﻿using System.IO;
using MediaBrowser.Library.Filesystem;
using MediaBrowser.LibraryManagement;
using MediaBrowser.Library.Entities;
using MusicPlugin.Util;
using System;
using MediaBrowser.Library.Extensions;
using MediaBrowser.Library.Logging;
using System.Collections.Generic;
using MusicPlugin.Code;
using System.Net;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.Web;
using System.Text;
using System.ServiceModel;
using System.Windows.Forms;

namespace MusicPlugin.LibraryManagement
{
    public static class MusicHelper
    {
        public static string SecondsToHighestTwoUnits(int seconds)
        {
            TimeSpan timeSpan = new TimeSpan(0, 0, seconds);
            int count = 0;
            string result = "";

            if (timeSpan.Days != 0)
            {
                result = timeSpan.Days.ToString() + "d ";
                count++;
            }

            if (timeSpan.Hours != 0 || count == 1)
            {
                result += timeSpan.Hours.ToString() + "h ";
                count++;
            }

            if (count == 2) return result;

            if (timeSpan.Minutes != 0 || count == 1)
            {
                result += timeSpan.Minutes.ToString() + "m ";
                count++;
            }

            if (count == 2) return result;

            return timeSpan.Minutes.ToString().PadLeft(2, '0') + ":" + timeSpan.Seconds.ToString().PadLeft(2, '0');
        }
        public static string SecondsToDDHHMM(int seconds)
        {
            TimeSpan timeSpan = new TimeSpan(0,0,seconds);
            string result = timeSpan.Days == 0 ? "" : timeSpan.Days + "Days ";
            return result + timeSpan.Hours.ToString().PadLeft(2, '0') + ":" + timeSpan.Minutes.ToString().PadLeft(2, '0');
        }
        public static string SecondsToHHMMSS(int seconds)
        {
            TimeSpan timeSpan = new TimeSpan(0, 0, seconds);
            string result = timeSpan.Hours == 0 ? "" : timeSpan.Hours.ToString().PadLeft(2, '0') + ":";
            return result + timeSpan.Minutes.ToString().PadLeft(2, '0')
                + ":" + timeSpan.Seconds.ToString().PadLeft(2, '0');
        }
        public static bool IsHidden(string filename)
        {
            if (Path.HasExtension(filename))
                return (new System.IO.FileInfo(filename).Attributes & FileAttributes.Hidden) == FileAttributes.Hidden;
            else
                return (new System.IO.DirectoryInfo(filename).Attributes & FileAttributes.Hidden) == FileAttributes.Hidden;
        }

        public static bool IsArtistFolder(this IMediaLocation location)
        {
            IFolderMediaLocation folder = location as IFolderMediaLocation;
            if (folder != null)
            {
                if (Path.HasExtension(folder.Path))
                    return false;

                if (MusicHelper.IsAlbumFolder(folder.Path))
                    return false;

                DirectoryInfo directoryInfo = new DirectoryInfo(folder.Path);
                foreach (DirectoryInfo directory in directoryInfo.GetDirectories())
                    if (IsAlbumFolder(directory.FullName))
                        return true;

                return false;


            }
            return false;
        }

        public static bool IsPlaylistFolder(string folder)
        {
            return true;
        }

        public static bool IsMusic(string filename)
        {
            string extension = System.IO.Path.GetExtension(filename).ToLower();

            switch (extension)
            {
                case ".mp3":
                case ".m3u":
                case ".wav":
                case ".wma":
                case ".acc":
                case ".flac":
                case ".m4a":
                case ".wpl":
                    return true;

                default:
                    return false;
            }
        }

        public static bool IsAlbumFolder(string path)
        {
            if (Path.HasExtension(path))
                return false;

            DirectoryInfo directoryInfo = new DirectoryInfo(path);
            foreach (System.IO.FileInfo fileInfo in directoryInfo.GetFiles())
                if (MusicHelper.IsMusic(fileInfo.FullName))
                    return true;

            return false;
        }

        public static bool IsArtistAlbumFolder(string path)
        {
            if (Path.HasExtension(path))
                return false;

            DirectoryInfo directoryInfo = new DirectoryInfo(path);
            foreach (System.IO.FileInfo fileInfo in directoryInfo.GetFiles())
                if (MusicHelper.IsMusic(fileInfo.FullName))
                    return true;

            return false;
        }

        public static bool IsMusicFolder(string path)
        {
            if (Path.HasExtension(path))
                return false;

            DirectoryInfo directoryInfo = new DirectoryInfo(path);
            foreach (System.IO.FileInfo fileInfo in directoryInfo.GetFiles())
                if (MusicHelper.IsMusic(fileInfo.FullName))
                    return false;

            foreach (var dirInfo in directoryInfo.GetDirectories())
            {
                if (MusicHelper.IsArtistAlbumFolder(dirInfo.FullName))
                    return true;
            }

            return false;
        }

        private static Folder _playlistFolder;
        public static Folder GetPlaylistFolder()
        {
            if (_playlistFolder == null)
            {
                string playListPath = System.Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);

                if (!Directory.Exists(playListPath))
                {
                    Logger.ReportError("MusicPlugin Error, failed to find special music folder, " + playListPath);
                    return null;
                }

                playListPath = Path.Combine(playListPath, "PlayLists");

                if (!Directory.Exists(playListPath))
                {
                    try
                    {
                        Directory.CreateDirectory(playListPath);
                    }
                    catch (Exception e)
                    {
                        Logger.ReportException("MusicPlugin Error, failed to create playlists folder, " + playListPath,e);
                        return null;
                    }                    
                }

                _playlistFolder = new Folder();
                _playlistFolder.Name = Settings.Instance.PlayListFolderName;
                _playlistFolder.Path = playListPath;
                _playlistFolder.Id = playListPath.GetMD5();
            }
            return _playlistFolder;
        }

        public static void AddToList(string item, string conjunction, string item2, List<string> list)
        {
            if (!string.IsNullOrEmpty(item2) && !string.IsNullOrEmpty(item) && !list.Contains(item))
                list.Add(item+conjunction+item2);
        }
        public static void AddToList(string item, List<string> list)
        {
            if (!string.IsNullOrEmpty(item) && !list.Contains(item))
                list.Add(item);
        }
        public static void AddToList(List<string> items, List<string> list)
        {
            if (items == null) return;

            foreach (var item in items)
            {
                if (!string.IsNullOrEmpty(item) && !list.Contains(item))
                    list.Add(item);
            }
        }

        //public static string GetLyricWikiLyrics(string artist, string song)
        //{
        //    if (string.IsNullOrEmpty(artist) || string.IsNullOrEmpty(song))
        //        return string.Empty;

        //    LyricWiki.LyricWikiPortTypeClient wiki = new LyricWiki.LyricWikiPortTypeClient();
            
        //    LyricWiki.LyricsResult result;            

        //    if(wiki.checkSongExists(artist,song))
        //    {
        //        result = wiki.getSong(artist, song);
        //        //Encoding iso8859 = Encoding.GetEncoding("ISO-8859-1");
        //        //return Encoding.UTF8.GetString(iso8859.GetBytes(result.lyrics));
        //        Logger.ReportInfo("MusicPlugin, got lyrics: " + result.lyrics);
        //        return result.lyrics;

        //    }
        //    return string.Empty;
        //}

        //public static string GetChartLyricsLyrics(string artist, string song)
        //{
        //    if (string.IsNullOrEmpty(artist) || string.IsNullOrEmpty(song))
        //        return string.Empty;

        //    //var binding = new System.ServiceModel.Channels.Binding();
        //    //var endPoint = new EndpointAddress("http://api.chartlyrics.com/apiv1.asmx");
            
        //    using (ChartLyrics.apiv1HttpGetClient chartLyrics = new MusicPlugin.ChartLyrics.apiv1HttpGetClient())
        //    {
        //        var results = chartLyrics.SearchLyric(artist, song);

        //        if (results.Length > 0)
        //        {
        //            var result = chartLyrics.GetLyric(results[0].LyricId.ToString(), results[0].LyricChecksum);
        //            Logger.ReportInfo("MusicPlugin, got lyrics: " + result.Lyric);
        //            return result.Lyric;
        //        }
        //    }
        //    return string.Empty;
        //}

        public static string LyricsFlyRequestURL(string artist, string title)
        {
            return string.Format(Global.LYRICSFLY_URL_ARTIST_TITLE,  HttpUtility.UrlEncode(artist),  HttpUtility.UrlEncode(title));
        }

        public static string GetLyrics(string artist, string title)
        {
            #region LyricsFly Information
            //http://lyricsfly.com/api/
            //Tag description
            //<status>
            //<delay>
            //<sg> - song
            //<cs> - checksum (for original URL link back construction)
            //<id> - song ID in the database (for original URL link back construction)
            //<ar> - artist name
            //<tt> - title of the song
            //<al> - album name
            //<tx> - lyrics text separated by [br] for line break (replace with <br>)

            //Status and error description
            //200 – ok
            //    Results are returned. All parameters checked ok.
            //204 - NO CONTENT
            //    Parameter query returned no results. All parameters checked ok.
            //300 - TESTING LIMITED
            //    Temporary access. Limited content. All parameters checked ok.
            //400 - MISSING KEY
            //    Parameter “i” missing. Authorization failed.
            //401 – UNAUTHORIZED
            //    Parameter “i” invalid. Authorization failed.
            //402 - LIMITED TIME
            //    This response is returned only if you query too soon. Limit query requests. Time of delay is shown in <delay> tag in milliseconds.
            //406 - QUERY TOO SHORT
            //    Query request string is too short. All other parameters checked ok.
            #endregion

            using (WebClient client = new WebClient())
            {
                //XmlDocument xDoc = new XmlDocument();
                try
                {
                    string output = client.DownloadString(LyricsFlyRequestURL(artist, title));
                    //string data;
                    //HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(LyricsFlyRequestURL(artist, title));
                    //HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    //using (Stream stream = response.GetResponseStream())
                    //{
                    //    StreamReader reader = new StreamReader(stream);
                    //    data = reader.ReadToEnd();
                    //}
                    //xDoc.LoadXml(output);
                    var lyricsFlyReponseObject = ParseLyricsFlyDoc(output);

                    return lyricsFlyReponseObject.Lyrics;
                }
                catch (Exception e)
                {
                    Logger.ReportException("MusicPlugin could not get lyrics for "+artist+" - " +title, e);
                    return string.Empty;
                }                
            }
        }

        //private static LyricsFlyReponseObject LoadLyricsFlyXML(string xml)
        //{
        //    XmlSerializer ser = new XmlSerializer(typeof(LyricsFlyReponseObject));

        //    System.Text.ASCIIEncoding  encoding=new System.Text.ASCIIEncoding();

        //    var reader = new MemoryStream(encoding.GetBytes(xml));
        //    var result = (LyricsFlyReponseObject)ser.Deserialize(reader);
        //    reader.Close();
        //    return result;
        //}

        private static LyricsFlyReponseObject ParseLyricsFlyDoc(string xml)
        {
            var lyricFlyReponseObject = new LyricsFlyReponseObject();
            Logger.ReportInfo(xml);
            XElement doc = XElement.Parse(xml);
            if (doc.Element("status") == null)
                Logger.ReportInfo("justin1");
            else
                Logger.ReportInfo(doc.Element("status").Value);
            if (doc.Element("start").Element("status") == null)
                Logger.ReportInfo("justin2");
            if (doc.Element("start").Element("status").Value == null)
                Logger.ReportInfo("justin3");
            if (doc.Element("start").Element("status").Value.Equals("200"))
            {
                
                lyricFlyReponseObject.Status = doc.Element("start").Element("status").Value;
                lyricFlyReponseObject.Lyrics = doc.Element("start").Element("sg").Element("tx").Value;
            }
            //lyricFlyReponseObject.Lyrics = xDoc.SelectSingleNode("start/sg/tx").Value.ToString();
            //lyricFlyReponseObject.Status = xDoc.SelectSingleNode("start/status").Value.ToString();

            return lyricFlyReponseObject;
        }

    }

    public class LyricsFlyReponseObject
    {
        public LyricsFlyReponseObject() { }
        //public string sg { get; set; }
        //public string status { get; set; }
        //public string delay { get; set; }
        //public string cs { get; set; }
        //public string id { get; set; }
        //public string ar { get; set; }
        //public string tt { get; set; }
        //public string al { get; set; }
        //public string tx { get; set; }
        public string Status { get; set; }
        public string Lyrics { get; set; }
    }
}

